package TMSTransport

import (
	"fmt"
	CoreSQL "gitee.com/fotomxq/weeekj_core/v5/core/sql"
	CoreSQLTime "gitee.com/fotomxq/weeekj_core/v5/core/sql/time"
	Router2SystemConfig "gitee.com/fotomxq/weeekj_core/v5/router2/system_config"
	"strings"
)

// ArgsGetAnalysisCashSum 获取配送员
type ArgsGetAnalysisCashSum struct {
	//组织ID
	OrgID int64 `db:"org_id" json:"orgID" check:"id"`
	//配送人员
	BindID int64 `db:"bind_id" json:"bindID" check:"id" empty:"true"`
	//收付款类型
	// 0 收款(配送员收到款项) 1 付款(配送员付出款项)
	PayType int `db:"pay_type" json:"payType"`
	//时间范围
	// 部分统计支持
	TimeBetween CoreSQLTime.DataCoreTime `json:"timeBetween"`
	//配送类型1-普通配送 2-既是普通配送又是大客户配送
	DeliveryType int64 `db:"delivery_type" json:"deliveryType"`
}

func GetAnalysisCashSum(args *ArgsGetAnalysisCashSum) (count int64, err error) {
	var timeBetween CoreSQLTime.FieldsCoreTime
	timeBetween, err = CoreSQLTime.GetBetweenByISO(args.TimeBetween)
	if err != nil {
		return
	}

	// 1. 取出符合条件的 transport 记录
	dataList, err := GetTransportByBindIDAndTimeAndTransportType(
		args.OrgID, args.BindID, timeBetween, args.DeliveryType)
	if err != nil {
		return
	}

	// 2. 提取 id 列表
	transportIds := make([]int64, 0, len(dataList))
	for _, v := range dataList {
		transportIds = append(transportIds, v.ID)
	}

	// 3. 如果没有记录，直接返回 0
	if len(transportIds) == 0 {
		return 0, nil
	}

	// 4. 构造 IN (?) 占位符
	idsPlaceholder := make([]string, len(transportIds))
	for i := range transportIds {
		idsPlaceholder[i] = fmt.Sprintf("$%d", i+6) // 前面已有 5 个参数
	}
	inExpr := strings.Join(idsPlaceholder, ",")

	// 5. 构造参数切片（顺序与 SQL 中的 $1,$2,... 对应）
	sqlArgs := []interface{}{
		args.OrgID,
		args.BindID,
		args.PayType,
		timeBetween.MinTime,
		timeBetween.MaxTime,
	}
	for _, id := range transportIds {
		sqlArgs = append(sqlArgs, id)
	}

	// 6. 拼最终 SQL
	where := fmt.Sprintf(
		`org_id = $1 AND ($2 < 1 OR bind_id = $2) AND
		 create_at >= $4 AND create_at <= $5 AND
		 ($3 < 0 OR pay_type = $3) AND
		 transport_id IN (%s)`, inExpr)

	// 7. 调用底层求和（CoreSQL.GetAllSumMap 支持占位符写法）
	count, err = CoreSQL.GetAllSumMap(Router2SystemConfig.MainDB.DB,
		"tms_transport_cash", "price", where, sqlArgs)
	return
}

// GetAnalysisCashSumOld 旧版统计代码，暂时保留
func GetAnalysisCashSumOld(args *ArgsGetAnalysisCashSum) (count int64, err error) {
	var timeBetween CoreSQLTime.FieldsCoreTime
	timeBetween, err = CoreSQLTime.GetBetweenByISO(args.TimeBetween)
	if err != nil {
		return
	}
	count, err = CoreSQL.GetAllSumMap(Router2SystemConfig.MainDB.DB, "tms_transport_cash", "price", "org_id = :org_id AND (:bind_id < 1 OR bind_id = :bind_id) AND create_at >= :start_at AND create_at <= :end_at AND (:pay_type < 0 OR pay_type = :pay_type)", map[string]interface{}{
		"org_id":   args.OrgID,
		"bind_id":  args.BindID,
		"pay_type": args.PayType,
		"start_at": timeBetween.MinTime,
		"end_at":   timeBetween.MaxTime,
	})
	return
}

// ArgsGetAnalysisCashSumV2 获取配送员 大客户版
type ArgsGetAnalysisCashSumV2 struct {
	//组织ID
	OrgID int64 `db:"org_id" json:"orgID" check:"id"`
	//配送人员
	BindID int64 `db:"bind_id" json:"bindID" check:"id" empty:"true"`
	//收付款类型
	// 0 收款(配送员收到款项) 1 付款(配送员付出款项)
	PayType int `db:"pay_type" json:"payType"`
	//时间范围
	// 部分统计支持
	TimeBetween CoreSQLTime.DataCoreTime `json:"timeBetween"`
	//特殊配送员ids
	SpecialBindIDs []int64 `db:"special_bind_ids" json:"specialBindIDs" check:"id" empty:"true"`
}

func GetAnalysisCashSumV2(args *ArgsGetAnalysisCashSumV2) (count int64, err error) {
	var timeBetween CoreSQLTime.FieldsCoreTime
	timeBetween, err = CoreSQLTime.GetBetweenByISO(args.TimeBetween)
	if err != nil {
		return
	}
	passIDsStr := "(" + strings.Join(sliceToString(args.SpecialBindIDs), ",") + ")"
	count, err = CoreSQL.GetAllSumMap(Router2SystemConfig.MainDB.DB, "tms_transport_cash", "price", "org_id = :org_id AND (:bind_id < 1 OR bind_id = :bind_id) AND create_at >= :start_at AND create_at <= :end_at AND (:pay_type < 0 OR pay_type = :pay_type ) AND bind_id in :special_bind_ids", map[string]interface{}{
		"org_id":            args.OrgID,
		"bind_id":           args.BindID,
		"pay_type":          args.PayType,
		"start_at":          timeBetween.MinTime,
		"end_at":            timeBetween.MaxTime,
		":special_bind_ids": passIDsStr,
	})
	return
}
func sliceToString(slice []int64) []string {
	strSlice := make([]string, len(slice))
	for i, v := range slice {
		strSlice[i] = fmt.Sprintf("'%d'", v)
	}
	return strSlice
}
